<!DOCTYPE html>
<html>
<head>
    <title>高级参数分析系统</title>
    <style>
        .container { width: 1000px; margin: 50px auto; }
        .input-group { margin: 10px 0; display: grid; grid-template-columns: 250px 120px 120px 40px; align-items: center; gap: 10px; }
        .param-select { width: 100%; }
        .bound-input { background: #f5f5f5; }
        .current-input { background: #fff; }
        button { padding: 6px 12px; }
        th { background: #f0f0f0; }
        .results-table { width: 100%; border-collapse: collapse; margin-top: 15px; }
        .results-table th, .results-table td { padding: 6px; text-align: right; border: 1px solid #ddd; font-size: 12px; }
        .results-table td:first-child { text-align: left; }
        .positive-change { color: green; font-weight: bold; }
        .negative-change { color: red; font-weight: bold; }
        .no-change { color: gray; }
        .new-value-header, .change-percent-header { background-color: #5cb85c; color: white; }
        .model-results-section { margin-bottom: 30px; }
        .search-box { width: 100%; padding: 8px; margin-bottom: 10px; box-sizing: border-box; }
        .results-container { max-height: 400px; overflow-y: auto; overflow-x: auto; border: 1px solid #ddd; }
        #threePGTable th, #threePGTable td { min-width: 80px; }
    </style>
</head>
<body>
    <div class="container">
        <h1>高级参数分析系统</h1>

        <!-- 3PG模型计算结果区域 -->
        <div class="model-results-section">
            <h2>3PG模型计算结果</h2>
            <input type="text" id="resultSearch" class="search-box" placeholder="搜索结果变量...">
            <div id="modelResults">
                {% if model_results %}
                <div class="results-container">
                    <table class="results-table">
                        <thead>
                            <tr>
                                <th>英文变量</th>
                                <th>中文描述</th>
                                <th>原始值</th>
                                <th class="new-value-header">新计算值</th>
                                <th class="change-percent-header">变化(%)</th>
                            </tr>
                        </thead>
                        <tbody id="resultsBody">
                            {% for result in model_results %}
                            <tr>
                                <td>{{ result.english }}</td>
                                <td>{{ result.chinese }}</td>
                                <td>{{ result.value }}</td>
                                <td class="new-value">-</td>
                                <td class="change-percent">-</td>
                            </tr>
                            {% endfor %}
                        </tbody>
                    </table>
                </div>
                {% else %}
                <p>暂无模型计算结果</p>
                {% endif %}
            </div>
        </div>

        <!-- 参数输入区 -->
        <div class="input-section">
            <h2>参数输入（每个参数包含下界和当前值）</h2>
            <div id="inputContainer">
                {% for _ in range(3) %}
                <div class="input-group">
                    <select class="param-select">
                        {% for param in available_parameters %}
                        <option value="{{ param.name }}" data-lb="{{ param.lower_bound }}" data-ub="{{ param.upper_bound }}">
                            {{ param.name }} ({{ param.unit }})
                        </option>
                        {% endfor %}
                    </select>
                    <input type="number" class="bound-input" value="{{ available_parameters[0].lower_bound }}" readonly>
                    <input type="number" class="current-input" value="{{ available_parameters[0].lower_bound }}" step="any" min="{{ available_parameters[0].lower_bound }}" max="{{ available_parameters[0].upper_bound }}">
                    <button type="button" onclick="removeRow(this)">×</button>
                </div>
                {% endfor %}
            </div>
            <button type="button" onclick="addRow()">+ 添加参数</button>
            <button type="button" onclick="calculateSum()">计算结果</button>
        </div>

        <!-- 分析功能区 -->
        <div class="analysis-section">
            <h2>参数分析</h2>
            <button type="button" onclick="analyzeSensitivity('3pg')">3PG模型敏感性分析</button>
            <button type="button" onclick="runOptimization()" id="optimizeBtn" disabled>执行优化</button>

            <!-- 3PG模型敏感性分析结果 -->
            <div id="threePGAnalysisResult" style="display: none;">
                <h3>3PG模型敏感性分析结果</h3>
                <div id="actualResultsInput">
                    <h4>输入实际结果</h4>
                    <div class="results-container">
                        <table class="results-table" id="actualResultsTable">
                            <thead id="actualResultsHeader"></thead>
                            <tbody id="actualResultsBody"></tbody>
                        </table>
                    </div>
                </div>
                <input type="text" id="threePGSearch" class="search-box" placeholder="搜索参数或变量...">
                <h4>敏感性分析结果μ：表示某个参数对模型输出的平均影响程度如果μ值较大，说明该参数的变化会导致模型输出的显著变化，即该参数对模型输出高度敏感。</h4>
                <div class="results-container">
                    <table class="results-table" id="threePGTable">
                        <thead id="threePGHeader"></thead>
                        <tbody id="threePGBody"></tbody>
                    </table>
                </div>
            </div>

            <!-- 优化进度和结果 -->
            <div id="optimizationProgress" style="display: none; text-align: center; margin-top: 10px;">
                <p>正在优化，请稍候... <span id="estimatedTime"></span></p>
                <progress id="progressBar" value="0" max="100" style="width: 100%;"></progress>
            </div>
            <div id="optimizationResult" style="display: none;">
                <h3>优化结果</h3>
                <p>最优目标差值: <span id="optimalValue"></span></p>
                <table>
                    <thead><tr><th>参数</th><th>优化值</th></tr></thead>
                    <tbody id="optimizedParams"></tbody>
                </table>
            </div>
        </div>
    </div>

    <script>
        var availableParams = {{ available_parameters | tojson }};

        function getVariableMapping() {
            return {
                "林木数量 (株/ha)": "StemNo", "叶生物量 (t/ha)": "WF", "根生物量 (t/ha)": "WR", "茎生物量 (t/ha)": "WS",
                "枯落物 (t/ha)": "WL", "林分材积 (m³/ha)": "StandVol", "叶面积指数 (m²/m²)": "LAI", "平均胸径 (cm)": "avDBH",
                "灌溉量 (mm)": "Irrig", "茎生物量增量 (t/ha)": "incrWS", "死亡率 (%)": "mortality", "自疏 (株/ha)": "selfThin",
                "平均温度 (°C)": "meantemp", "肥力等级": "FR", "CO2浓度 (ppm)": "CO2", "最小可用土壤水 (mm)": "minASW",
                "林龄 (年)": "StandAge", "断面积 (m²/ha)": "BasArea", "树高 (m)": "Height", "平均年生长量 (m³/ha/年)": "MAI",
                "最大平均年生长量 (m³/ha/年)": "MAIx", "最大MAI年龄 (年)": "ageMAIx", "比叶面积 (m²/kg)": "SLA",
                "郁闭度 (%)": "CanCover", "最大LAI (m²/m²)": "LAIx", "最大LAI年龄 (年)": "ageLAIx", "总生物量 (t/ha)": "TotalW",
                "平均单株茎重 (kg)": "AvStemMass", "密度 (株/ha)": "Density", "树皮比例": "fracBB", "年龄修正因子": "fAge",
                "VPD修正因子": "fVPD", "温度修正因子": "fTemp", "CO2对量子效率影响": "fCalpha", "CO2对气孔导度影响": "fCg",
                "霜冻修正因子": "fFrost", "水分修正因子": "fSW", "养分修正因子": "fNutr", "生理修正因子": "PhysMod",
                "总初级生产力 (tC/ha)": "GPP", "净初级生产力 (tC/ha)": "NPP", "截获辐射 (MJ/m²)": "RADint",
                "冠层量子效率": "alphaC", "光能利用效率 (gDM/MJ)": "Epsilon", "冠层体积指数": "CVI", "生物量分配系数": "m",
                "分配至根的比例": "pR", "分配至茎的比例": "pS", "分配至叶的比例": "pF", "叶茎分配比": "pFS",
                "叶凋落率 (1/月)": "gammaF", "最大单株茎重 (kg)": "wSmax", "死亡率 (%/年)": "gammaN", "补充灌溉 (mm)": "supIrrig",
                "径流 (mm)": "RunOff", "雨水截留比例": "fRainInt", "雨水截留量 (mm)": "RainInt", "冠层导度 (m/s)": "CanCond",
                "水分利用效率 (gDM/kg水)": "WUE", "蒸散发 (mm)": "ET", "蒸腾 (mm)": "Transp", "可用土壤水 (mm)": "ASW",
                "日长 (h)": "DayLength", "霜冻日数 (天)": "FrostDays", "太阳辐射 (MJ/m²)": "SolarRad", "平均温度 (°C)": "Tav",
                "饱和水汽压差 (mBar)": "VPD", "降雨量 (mm)": "Rain", "长期茎生长率 (t/ha/月)": "ltStemGR", "凋落物 (t/ha)": "Litter",
                "总凋落物 (t/ha)": "TotalLitter", "茎生长效率 (tDM/ha/MJ)": "EpsilonStem", "汇集土壤水 (mm)": "pooledSW",
                "温度函数": "fT"
            };
        }

        function getVariableName(displayName) {
            const mapping = getVariableMapping();
            return mapping[displayName] || displayName;
        }

        function getDisplayName(variableName) {
            const mapping = getVariableMapping();
            for (const [display, variable] of Object.entries(mapping)) {
                if (variable === variableName) return display;
            }
            return variableName;
        }

        function updateModelResults(newModelResults) {
            const resultsBody = document.getElementById('resultsBody');
            if (!resultsBody || !newModelResults) return;

            const rows = resultsBody.querySelectorAll('tr');
            rows.forEach(row => {
                const englishName = row.cells[0].textContent;
                const originalValue = parseFloat(row.cells[2].textContent);
                const newValueCell = row.querySelector('.new-value');
                const changePercentCell = row.querySelector('.change-percent');

                const newResult = newModelResults.find(result => result.english === englishName);
                if (newResult) {
                    const newValue = newResult.value;
                    newValueCell.textContent = newValue.toFixed(4);
                    if (!isNaN(originalValue) && originalValue !== 0) {
                        const changePercent = ((newValue - originalValue) / originalValue * 100).toFixed(2);
                        changePercentCell.textContent = changePercent + '%';
                        changePercentCell.className = 'change-percent ' + (changePercent > 0 ? 'positive-change' : changePercent < 0 ? 'negative-change' : 'no-change');
                    } else {
                        changePercentCell.textContent = '-';
                        changePercentCell.className = 'change-percent';
                    }
                } else {
                    newValueCell.textContent = '-';
                    changePercentCell.textContent = '-';
                    changePercentCell.className = 'change-percent';
                }
            });
        }

        function calculateSum() {
            const allParams = collectAllParameters();
            console.log('Sending parameters:', allParams);
            const resultsBody = document.getElementById('resultsBody');
            if (resultsBody) {
                const rows = resultsBody.querySelectorAll('tr');
                rows.forEach(row => {
                    const newValueCell = row.querySelector('.new-value');
                    const changePercentCell = row.querySelector('.change-percent');
                    if (newValueCell) newValueCell.textContent = "计算中...";
                    if (changePercentCell) changePercentCell.textContent = "";
                });
            }

            fetch('/sens/calculate', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ parameters: allParams })
            })
            .then(response => response.json())
            .then(data => {
                if (data.error) {
                    alert(`计算错误: ${data.error}`);
                    return;
                }
                if (data.model_results && resultsBody) {
                    updateModelResults(data.model_results);
                }
            })
            .catch(error => {
                console.error('计算请求失败:', error);
                alert('计算请求失败，请检查网络连接或服务器状态');
                if (resultsBody) {
                    const rows = resultsBody.querySelectorAll('tr');
                    rows.forEach(row => {
                        const newValueCell = row.querySelector('.new-value');
                        const changePercentCell = row.querySelector('.change-percent');
                        if (newValueCell) newValueCell.textContent = "-";
                        if (changePercentCell) changePercentCell.textContent = "-";
                    });
                }
            });
        }

        document.addEventListener('DOMContentLoaded', function () {
            const resultSearch = document.getElementById('resultSearch');
            if (resultSearch) {
                resultSearch.addEventListener('input', function () {
                    const searchTerm = this.value.toLowerCase();
                    const rows = document.querySelectorAll('#resultsBody tr');
                    rows.forEach(row => {
                        const variableName = row.cells[0].textContent.toLowerCase();
                        row.style.display = variableName.includes(searchTerm) ? '' : 'none';
                    });
                });
            }
            const threePGSearch = document.getElementById('threePGSearch');
            if (threePGSearch) {
                threePGSearch.addEventListener('input', function () {
                    const searchTerm = this.value.toLowerCase();
                    const rows = document.querySelectorAll('#threePGBody tr');
                    rows.forEach(row => {
                        const paramName = row.cells[0].textContent.toLowerCase();
                        row.style.display = paramName.includes(searchTerm) ? '' : 'none';
                    });
                });
            }

            document.querySelectorAll('#inputContainer .param-select').forEach(select => {
                select.addEventListener('change', function () {
                    const param = availableParams.find(p => p.name === this.value);
                    if (param) {
                        const row = this.closest('.input-group');
                        row.querySelector('.bound-input').value = param.lower_bound;
                        const currentInput = row.querySelector('.current-input');
                        currentInput.value = param.lower_bound;
                        currentInput.min = param.lower_bound;
                        currentInput.max = param.upper_bound;
                    }
                });
                select.dispatchEvent(new Event('change'));
            });
        });

        function collectAllParameters() {
            const rows = document.querySelectorAll('#inputContainer .input-group');
            const modifiedValues = {};
            rows.forEach(row => {
                const select = row.querySelector('.param-select');
                const currentInput = row.querySelector('.current-input');
                const name = select.value;
                const value = parseFloat(currentInput.value);
                if (!isNaN(value)) modifiedValues[name] = value;
            });
            console.log('Collected parameters:', modifiedValues);
            return availableParams.map(param => ({
                name: param.name,
                value: (param.name in modifiedValues) ? modifiedValues[param.name] : param.lower_bound
            }));
            
        }

        function analyzeSensitivity(type) {
            if (type !== '3pg') return;
            const params = collectAllParameters();
            fetch('/sens/analyze_3pg', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ parameters: params })
            })
            .then(response => {
                if (!response.ok) return response.json().then(data => { throw new Error(data.error); });
                return response.json();
            })
            .then(data => renderThreePGAnalysisResult(data))
            .catch(error => {
                console.error("3PG分析请求失败:", error);
                alert(`3PG模型分析失败: ${error.message}`);
            });
        }

        function renderThreePGAnalysisResult(data) {
            const thead = document.getElementById('threePGHeader');
            const tbody = document.getElementById('threePGBody');
            const actualHeader = document.getElementById('actualResultsHeader');
            const actualBody = document.getElementById('actualResultsBody');
            thead.innerHTML = '';
            tbody.innerHTML = '';
            actualHeader.innerHTML = '';
            actualBody.innerHTML = '';

            let actualHeaderRow = '<tr><th>变量</th>';
            data.output_vars.forEach(varName => {
                const displayName = getDisplayName(varName);
                actualHeaderRow += `<th>${displayName}</th>`;
            });
            actualHeaderRow += '</tr>';
            actualHeader.innerHTML = actualHeaderRow;

            let actualInputRow = '<tr><td>实际值</td>';
            data.output_vars.forEach((varName) => {
                actualInputRow += `<td><input type="number" class="actual-input" data-var="${varName}" step="any" style="width: 70px;"></td>`;
            });
            actualInputRow += '</tr>';
            actualBody.innerHTML = actualInputRow;

            let headerRow = '<tr><th>参数名称</th>';
            data.output_vars.forEach(varName => {
                const displayName = getDisplayName(varName);
                headerRow += `<th>${displayName}</th>`;
            });
            headerRow += '</tr>';
            thead.innerHTML = headerRow;

            data.names.forEach((paramName, paramIdx) => {
                const row = document.createElement('tr');
                let rowHTML = `<td>${paramName}</td>`;
                data.mu_star[paramIdx].forEach((mu, varIdx) => {
                    rowHTML += `
                        <td>
                            ${mu.toFixed(3)}
                            <br>
                            <input type="checkbox" class="optimize-checkbox" 
                                data-param="${paramIdx}" data-var="${varIdx}" 
                                title="优化 ${paramName} 对 ${data.output_vars[varIdx]}">
                        </td>`;
                });
                row.innerHTML = rowHTML;
                tbody.appendChild(row);
            });

            document.getElementById('threePGAnalysisResult').style.display = 'block';
            document.getElementById('optimizeBtn').disabled = false;
        }

        function runOptimization() {
            const selected3PG = [];
            document.querySelectorAll('#threePGBody .optimize-checkbox:checked').forEach(checkbox => {
                const paramIdx = parseInt(checkbox.getAttribute('data-param'));
                const varIdx = parseInt(checkbox.getAttribute('data-var'));
                selected3PG.push({ param_idx: paramIdx, var_idx: varIdx });
            });

            if (selected3PG.length === 0) {
                alert("请至少选择一个参数进行优化");
                return;
            }

            const currentValues = collectAllParameters();
            const actualResults = {};
            document.querySelectorAll('#actualResultsBody .actual-input').forEach(input => {
                const varName = input.getAttribute('data-var');
                const value = parseFloat(input.value);
                if (!isNaN(value)) actualResults[varName] = value;
            });
            if (Object.keys(actualResults).length === 0) {
                alert("请至少输入一个实际结果值");
                return;
            }

            document.getElementById("optimizationProgress").style.display = "block";
            document.getElementById("progressBar").value = 0;
            document.getElementById("estimatedTime").textContent = "预计需要10-30秒...";

            let interval = setInterval(() => {
                let progressBar = document.getElementById("progressBar");
                let currentValue = parseFloat(progressBar.value);
                if (currentValue < 90) progressBar.value = currentValue + 5;
            }, 1000);

            fetch('/sens/optimize_3pg', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({
                    selected_params: selected3PG,
                    current_values: currentValues,
                    actual_results: actualResults
                })
            })
            .then(response => {
                if (!response.ok) return response.json().then(data => { throw new Error(data.error); });
                return response.json();
            })
            .then(data => {
                clearInterval(interval);
                document.getElementById("progressBar").value = 100;
                document.getElementById("estimatedTime").textContent = `优化完成！耗时 ${data.elapsed_time} 秒`;
                setTimeout(() => { document.getElementById("optimizationProgress").style.display = "none"; }, 1000);

                document.getElementById('optimalValue').textContent = data.optimal_value.toFixed(6);
                const tbody = document.getElementById('optimizedParams');
                tbody.innerHTML = '';
                currentValues.forEach((param, paramIdx) => {
                    const row = document.createElement('tr');
                    const value = data.optimal_params[paramIdx][selected3PG[0].var_idx]; // 默认显示第一个选中的变量优化值
                    row.innerHTML = `<td>${param.name}</td><td>${value !== null ? value.toFixed(6) : '-'}</td>`;
                    tbody.appendChild(row);
                });

                document.getElementById('optimizationResult').style.display = 'block';
            })
            .catch(error => {
                clearInterval(interval);
                document.getElementById("optimizationProgress").style.display = "none";
                console.error("优化请求失败:", error);
                alert(`优化失败: ${error.message}`);
            });
        }

        function addRow() {
            const container = document.getElementById('inputContainer');
            const newRow = document.createElement('div');
            newRow.className = 'input-group';

            let options = '';
            availableParams.forEach(param => {
                options += `<option value="${param.name}" data-lb="${param.lower_bound}" data-ub="${param.upper_bound}">
                    ${param.name} (${param.unit})
                </option>`;
            });

            const initialParam = availableParams[0];
            newRow.innerHTML = `
                <select class="param-select">${options}</select>
                <input type="number" class="bound-input" value="${initialParam.lower_bound}" readonly>
                <input type="number" class="current-input" value="${initialParam.lower_bound}" step="any" min="${initialParam.lower_bound}" max="${initialParam.upper_bound}">
                <button type="button" onclick="removeRow(this)">×</button>
            `;

            const select = newRow.querySelector('select');
            select.addEventListener('change', function () {
                const selectedParam = availableParams.find(p => p.name === this.value);
                const boundInput = this.parentNode.querySelector('.bound-input');
                const currentInput = this.parentNode.querySelector('.current-input');
                boundInput.value = selectedParam.lower_bound;
                currentInput.value = selectedParam.lower_bound;
                currentInput.min = selectedParam.lower_bound;
                currentInput.max = selectedParam.upper_bound;
            });

            container.appendChild(newRow);
        }

        function removeRow(btn) {
            if (document.querySelectorAll('#inputContainer .input-group').length > 1) {
                btn.closest('.input-group').remove();
            }
        }
    </script>
</body>
</html>